package service

import (
	"errors"
	"gin_api/app/model"
	"gin_api/app/request"
	"gin_api/app/response"
	"gin_api/core/configure"
	"gin_api/core/logging"
	"gin_api/core/utils"
	"github.com/golang-jwt/jwt"
	"time"
)

type Auth struct {
	Username string `json:"username"`
	jwt.StandardClaims
}

// Login 用户登录
func (a Auth) Login(login *request.Login) (*response.Login, error) {
	// 登录验证
	userModel := &model.User{Username: login.Username, Status: model.StatusOK}
	userModel = userModel.FindUser()
	logging.New("app").Debug(userModel, login)
	if userModel == nil {
		err := errors.New("用户名不存在")
		return nil, err
	}
	// 密码校验
	if userModel.Password != utils.MD5WithString(login.Password) {
		err := errors.New("用户名或密码错误")
		return nil, err
	}
	// 生成Token
	a.Username = login.Username
	token, err := a.GenerateToken()
	if err != nil {
		return nil, err
	}
	// 响应
	return &response.Login{
		User:    userModel,
		Token:   token,
		Expires: a.StandardClaims.ExpiresAt,
	}, nil
}

// GenerateToken 生成jwt token
func (a *Auth) GenerateToken() (string, error) {
	expires := configure.GetInt("app.jwt.expires")
	a.StandardClaims.ExpiresAt = time.Now().Add(time.Second * time.Duration(expires)).Unix()
	// 使用指定的签名方法创建签名对象
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, a)
	// 使用指定的secret签名并获得完整的编码后的字符串token
	return token.SignedString([]byte(configure.GetString("app.jwt.secret")))
}

// ParseToken 解析token
func ParseToken(accessToken string) (*Auth, error) {
	// 解析token
	token, err := jwt.ParseWithClaims(accessToken, &Auth{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(configure.GetString("app.jwt.secret")), nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*Auth); ok && token.Valid {
		return claims, nil
	}
	return nil, errors.New("invalid token")
}
